package com.alon.spring01.common.exception;

import lombok.extern.slf4j.Slf4j;
import org.springframework.ui.Model;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;

/**
 * @program: spring01
 * @description: 全局异常捕获
 * @author: yulongguang
 * @create: 2019-07-25 10:38
 **/
@Slf4j
@RestControllerAdvice
public class UnionExceptionHandler {

    /**
     * 应用到所有@RequestMapping注解方法，在其执行之前初始化数据绑定器
     *
     * @param binder
     */
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        log.info("binder.getFieldDefaultPrefix {}", binder.getFieldDefaultPrefix());
        log.info("binder.getFieldMarkerPrefix {}", binder.getFieldMarkerPrefix());
    }

    /**
     * 把值绑定到Model中，使全局@RequestMapping可以获取到该值
     *
     * @param model
     */
    @ModelAttribute
    public void addAttributes(Model model) {
        model.addAttribute("author", "harry");
    }

    /**
     * Description : 全局异常捕捉处理
     * Group :
     *
     * @param ex
     * @return
     * @author yulongguang
     * @date 2019/7/25 0001 10:34
     */
    @ExceptionHandler(Exception.class)
    public Map apiExceptionHandler(Exception ex) {
        log.error("ApiException 异常抛出：{}", ex);
        Map map = new HashMap<>();
        map.put("code", 100);
        map.put("message", ex.getCause().getMessage());
        return map;
    }

    /**
     * @Description: 全局自定义异常捕获
     * @Param: [myEx]
     * @return: java.util.Map
     * @Author: yulongguang
     * @Date: 2019/7/25
     */
    @ExceptionHandler(MyException.class)
    public Map apiMyExceptionHandler(MyException myEx) {
        log.error("ApiMyException异常抛出：{}", myEx);
        Map map = new HashMap();
        map.put("code", myEx.getCode());
        map.put("message", myEx.getMessage());
        map.put("method", myEx.getMethod());
        map.put("descinfo", myEx.getDesc());
        return map;
    }

    /**
     * 校验异常
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Map handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error("handleMethodArgumentNotValidException异常抛出：{}", e);
        //拼接错误信息
        StringJoiner joiner = new StringJoiner(",");
        List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
        fieldErrors.forEach(fieldError -> {
            joiner.add(fieldError.getDefaultMessage());
        });
        Map map = new HashMap(16);
        map.put("code", 200);
        map.put("message", joiner.toString());
        return map;
    }

}
